GLuint positionsVBO;


int main() {

// Explicitly set device
	cudaGLSetGLDevice(0);
// Initialize OpenGL and GLUT

	glutDisplayFunc(display);
	
// Create buffer object and register it with CUDA

	glGenBuffers(1, positionsVBO);
	glBindBuffer(GL_ARRAY_BUFFER, &vbo);
	unsigned int size = width * height * 4 * sizeof(float);
	glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	cudaGLRegisterBufferObject(positionsVBO);
	
// Launch rendering loop
	glutMainLoop();
}


void display() {
// Map buffer object for writing from CUDA
float4* positions;
cudaGLMapBufferObject((void**)&positions, positionsVBO);
// Execute kernel
dim3 dimBlock(16, 16, 1);
dim3 dimGrid(width / dimBlock.x, height / dimBlock.y, 1);
createVertices<<<dimGrid, dimBlock>>>(positions, time,
Chapter 3. Programming Interface
CUDA Programming Guide Version 2.3.1 37
width, height);
// Unmap buffer object
cudaGLUnmapBufferObject(positionsVBO);
// Render from buffer object
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, positionsVBO);
glVertexPointer(4, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, width * height);
glDisableClientState(GL_VERTEX_ARRAY);
// Swap buffers
glutSwapBuffers();
glutPostRedisplay();
}
void deleteVBO()
{
cudaGLUnregisterBufferObject(positionsVBO);
glDeleteBuffers(1, &positionsVBO);
}
__global__ void createVertices(float4* positions, float time,
unsigned int width, unsigned int height)
{
unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;
// Calculate uv coordinates
float u = x / (float)width;
float v = y / (float)height;
u = u * 2.0f - 1.0f;
v = v * 2.0f - 1.0f;
// calculate simple sine wave pattern
float freq = 4.0f;
float w = sinf(u * freq + time)
* cosf(v * freq + time) * 0.5f;
// Write positions
positions[y * width + x] = make_float4(u, w, v, 1.0f);
}
